package utils;

import control.ValidateInput;
import basic.Date;
import enums.Frequency;
import enums.Gender;

//@author A0098891H
public class CommandAnalyzer {
	public static final int CMD_FORMAT_ERR = -1;
	public static final String PARAM_CATEGORY = "ca:";
	public static final String PARAM_MEMBER = "me:";
	public static final String PARAM_DATE = "dt:";
	public static final String PARAM_PAYMENTMETHOD = "pm:";
	public static final String PARAM_FREQUENCY = "fq:";
	public static final String PARAM_PARTYINVOLVED = "pi:";
	public static final String PARAM_COMMENTS = "cm:";
	public static final String PARAM_DUEDATE = "dd:";
	public static final String PARAM_GENDER = "gd:";
	public static final String PARAM_BIRTHDATE = "bd:";
	public static final String PARAM_INTEREST = "ir:";
	public static final String PARAM_UPDATEDATE = "ud:";
	public static final String PARAM_TOTALAMOUNT = "ta:";
	

	public static final int NA_CATEGORY = -1;
	public static final int NA_MEMBER = -1;
	public static final int NA_PAYMENTMETHOD = -1;
	public static final Frequency NA_FREQUENCY = Frequency.NA;
	public static final String NA_PARTYINVOLVED = "NA";
	public static final String NA_COMMENTS = "NA";
	public static final Gender NA_GENDER = Gender.NA;
	public static final double NA_INTEREST = -1.0;
	public static final double NA_TOTALAMOUNT = -1.0;
	
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static int getCategoryID(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_CATEGORY);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_CATEGORY.length()).trim();
					int id = Integer.parseInt(res);
					return id;
				}catch(NumberFormatException e)
				{
					return CMD_FORMAT_ERR;
				}
			}
		}
		return NA_CATEGORY;
	}

	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static int getMemberID(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_MEMBER);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_MEMBER.length()).trim();
					int id = Integer.parseInt(res);
					return id;
				}catch(NumberFormatException e)
				{
					return CMD_FORMAT_ERR;
				}
			}
		}
		return NA_MEMBER;
	}

	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static int getPaymentMethodID(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_PAYMENTMETHOD);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_PAYMENTMETHOD.length()).trim();
					int id = Integer.parseInt(res);
					return id;
				}catch(NumberFormatException e)
				{
					return CMD_FORMAT_ERR;
				}
			}
		}
		return NA_PAYMENTMETHOD;
	}
	
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static Date getDate(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_DATE);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_DATE.length()).trim();
					int day = 0, month = 0, year = 0;
					//14/3/2013 - <today, yesterday>
					String[] date = res.split("/");
					if(date!=null)
					{
						day = Integer.parseInt(date[0]);
						month = Integer.parseInt(date[1]);
						year = Integer.parseInt(date[2]);
					}
					else
					{
						//TODO - find related date
					}
					return new Date(day, month, year);
				}catch(Exception e)
				{
					return new Date(-1,-1,-1);
				}
			}
		}
		return Date.getCurrentDate();//if not found, return today's date
	}
	
	
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static Frequency getFrequency(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_FREQUENCY);
			if(index!=-1)
			{
				String res = str[i].substring(index+PARAM_FREQUENCY.length()).trim();
				for(Frequency freq: Frequency.values())
				{
					if(res.equalsIgnoreCase(freq.toString()))
					{
						return freq;
					}
				}
				switch(res.toLowerCase().trim())
				{
				case "no":
					return Frequency.NO;
				case "daily":
					return Frequency.DAILY;
				case "weekly":
					return Frequency.WEEKLY;
				case "monthly":
					return Frequency.MONTHLY;
				case "yearly":
					return Frequency.YEARLY;
				default:
					return NA_FREQUENCY;
				}
			}
		}
		return NA_FREQUENCY;
	}
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static String getPartyInvolved(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_PARTYINVOLVED);
			if(index!=-1)
			{
				return str[i].substring(index+PARAM_PARTYINVOLVED.length()).trim();
			}
		}
		return NA_PARTYINVOLVED;
	}
	
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static String getComments(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_COMMENTS);
			if(index!=-1)
			{
				return str[i].substring(index+PARAM_COMMENTS.length()).trim();
			}
		}
		return NA_COMMENTS;
	}
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static Date getDueDate(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_DUEDATE);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_DUEDATE.length()).trim();
					int day = 0, month = 0, year = 0;
					//14/3/2013 - <today, yesterday>
					String[] date = res.split("/");
					if(date!=null)
					{
						day = Integer.parseInt(date[0]);
						month = Integer.parseInt(date[1]);
						year = Integer.parseInt(date[2]);
					}
					else
					{
						//TODO - find related date
					}
					return new Date(day, month, year);
				}catch(Exception e)
				{
					return new Date(-1,-1,-1);
				}
			}
		}
		return new Date(-1,-1,-1);//if not found, no due date
	}
	
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static Gender getGender(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_GENDER);
			if(index!=-1)
			{
				String res = str[i].substring(index+PARAM_GENDER.length()).trim();
				for(Gender gd: Gender.values())
				{
					if(res.equalsIgnoreCase(gd.toString()))
					{
						return gd;
					}
				}
				switch(res.toLowerCase().trim())
				{
				case "male":
				case "m":
					return Gender.MALE;
				case "female":
				case "f":
					return Gender.FEMALE;
				default:
					return NA_GENDER;//input error
				}
			}
		}
		return NA_GENDER;
	}
	
	/**
	 * 
	 * @param str
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static Date getBirthDate(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_BIRTHDATE);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_BIRTHDATE.length()).trim();
					int day = 0, month = 0, year = 0;
					//14/3/2013 - <today, yesterday>
					String[] date = res.split("/");
					if(date!=null)
					{
						day = Integer.parseInt(date[0]);
						month = Integer.parseInt(date[1]);
						year = Integer.parseInt(date[2]);
					}
					else
					{
						//TODO - find related date
					}
					return new Date(day, month, year);
				}catch(Exception e)
				{
					return new Date(-1,-1,-1);
				}
			}
		}
		return new Date(-1,-1,-1);//if not found, no due date
	}

	
	public static double getInterest(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_INTEREST);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_INTEREST.length()).trim();
					double interest = Double.parseDouble(res);
					return interest;
				}catch(NumberFormatException e)
				{
					return CMD_FORMAT_ERR;
				}
			}
		}
		return NA_INTEREST;
	}

	public static double getTotalAmount(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_TOTALAMOUNT);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_TOTALAMOUNT.length()).trim();
					return Double.parseDouble(res);
				}catch(NumberFormatException e)
				{
					return CMD_FORMAT_ERR;
				}
			}
		}
		return NA_TOTALAMOUNT;
	}
	

	public static Date getUpdateDate(String str[])
	{
		for(int i = 2;i<str.length;i++)
		{
			int index = str[i].indexOf(PARAM_UPDATEDATE);
			if(index!=-1)
			{
				try{
					String res = str[i].substring(index+PARAM_UPDATEDATE.length()).trim();
					int day = 0, month = 0, year = 0;
					//14/3/2013 - <today, yesterday>
					String[] date = res.split("/");
					if(date!=null)
					{
						day = Integer.parseInt(date[0]);
						month = Integer.parseInt(date[1]);
						year = Integer.parseInt(date[2]);
					}
					else
					{
						//TODO - find related date
					}
					return new Date(day, month, year);
				}catch(Exception e)
				{
					return new Date(-1,-1,-1);
				}
			}
		}
		return Date.getCurrentDate();
	}

	public static boolean validateDateForLoanNInvestment(String[] str)
	{
		Date date = CommandAnalyzer.getDate(str);
		if(!date.equals(new Date(-1,-1,-1)))
			if(ValidateInput.validateDate(date)==ValidateInput.ERR_DATE_IMPOSSIBLE
			||ValidateInput.validateDate(date)==ValidateInput.ERR_TOO_LONG)
				return false;
		return true;
	}
	
	public static boolean validateDateForExpenseNIncome(String[] str)
	{
		Date date = CommandAnalyzer.getDate(str);
		if(!date.equals(new Date(-1,-1,-1)))
			if(ValidateInput.validateDate(date)==ValidateInput.ERR_DATE_IMPOSSIBLE
			||ValidateInput.validateDate(date)==ValidateInput.ERR_FUTURE_DATE
			||ValidateInput.validateDate(date)==ValidateInput.ERR_TOO_LONG)
				return false;
		return true;
	}
}
